package formatters;

import common.EntityPresentation;
import dao.Entity;
import dao.EntityDAO;
import database.DatabaseException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import localization.Localization;
import presentation.CurrencyElement;
import presentation.DateElement;
import presentation.EmailElement;
import presentation.LinkElement;
import presentation.PhoneElement;
import presentation.PresentationElement;
import presentation.TextElement;
import templates.PresentationTemplate;
import templates.PropertyTemplate;
import utils.GenericPair;

public class EditFormatter implements Formatter {

    private String output;

    @Override
    public String format(PresentationElement e) {
        e.acceptEdit(this);
        return output;
    }

    public void formatText(TextElement e) {
        PresentationTemplate pt = e.getTemplate();
        output = "<label for=\"edit" + pt.getAlias() + "\">" + Localization.getString(pt.getName()) + "</label><input type=\"text\" id=\"edit" + pt.getAlias() + "\" name=\"edit" + pt.getAlias() + "\" value=\"" + e.getValue() + "\" />";
    }

    public void formatPhone(PhoneElement e) {
        PresentationTemplate pt = e.getTemplate();
        PropertyTemplate template = pt.getPropertyTemplate();
        String value = (template.isNullEnabled() && e.getValue().equals(pt.getNullValue())) ? value = template.getNullValue() : e.getValue();
        output = "<label for=\"edit" + pt.getAlias() + "\">" + Localization.getString(pt.getName()) + "</label><input type=\"text\" id=\"edit" + pt.getAlias() + "\" name=\"edit" + pt.getAlias() + "\" value=\"" + value + "\" />";
    }

    public void formatEmail(EmailElement e) {
        PresentationTemplate pt = e.getTemplate();
        PropertyTemplate template = pt.getPropertyTemplate();
        String value = (template.isNullEnabled() && e.getValue().equals(pt.getNullValue())) ? value = template.getNullValue() : e.getValue();
        output = "<label for=\"edit" + pt.getAlias() + "\">" + Localization.getString(pt.getName()) + "</label><input type=\"text\" id=\"edit" + pt.getAlias() + "\" name=\"edit" + pt.getAlias() + "\" value=\"" + value + "\" />";
    }

    public void formatLink(LinkElement e) {
        try {
            PresentationTemplate pt = e.getTemplate();
            StringBuilder builder = new StringBuilder("<label for=\"edit");
            builder.append(pt.getAlias());
            builder.append("\">");
            builder.append(Localization.getString(pt.getName()));
            builder.append("</label><select id=\"edit");
            builder.append(pt.getAlias());
            builder.append("\" name=\"edit");
            builder.append(pt.getAlias());
            builder.append("\" size=\"1\">");

            String primaryKey = (String) e.getParam(LinkElement.PRIMARY_KEY);
            EntityDAO dao = new EntityDAO();
            Iterable<GenericPair<String,Boolean>> externals = pt.getExternals();
            short bindSource = e.getPropertyTemplate().getExternalUid();
            List<String> presentationNames = new LinkedList<String>();
            for (GenericPair<String,Boolean> ex : externals) {
                if (ex.getSecond()) {
                    presentationNames.add(ex.getFirst());
                }
            }

            dao.bind(bindSource);
            Iterable<EntityPresentation> container = dao.fastFindAll();
            //Iterable<EntityPresentation> container = dao.findAll();
            
            if (pt.getNullValue() != null) {
                builder.append("<option value=\"");
                PropertyTemplate pt2 = e.getPropertyTemplate();
                builder.append(pt2.getNullValue());
                builder.append("\"");
                if (e.getValue().equals(pt2.getNullValue())) {
                    builder.append(" selected=\"selected\"");
                }
                builder.append(">");
                builder.append(Localization.getString(pt.getNullValue()));
                builder.append("</option>");
            }

            for (EntityPresentation ep : container) {
                Entity ent = (Entity) ep;
                if ( (bindSource != (e.getUid() & 0xff00) ) || !primaryKey.equals(ent.getPrimaryKeyValue()))
                {
                    builder.append("<option value=\"");
                    builder.append(ent.getPrimaryKeyValue());
                    builder.append("\"");
                    if (ent.getPrimaryKeyValue().equals(e.getValue())) {
                        builder.append(" selected=\"selected\"");
                    }
                    builder.append(">");
                    for (String s : presentationNames) {
                        builder.append(ent.getPresentationElement(s).getValue());
                        builder.append(" ");
                    }
                    builder.append("</option>");
                }
            }


            builder.append("</select>");
            output = builder.toString();
        } catch (DatabaseException ex) {
            throw new RuntimeException(ex.getMessage());
        }
    }

    public void formatCurrency(CurrencyElement e) {
        PresentationTemplate pt = e.getTemplate();
        output = "<label for=\"edit" + pt.getAlias() + "\">" + Localization.getString(pt.getName()) + " $</label><input type=\"text\" id=\"edit" + pt.getAlias() + "\" name=\"edit" + pt.getAlias() + "\" value=\"" + e.getValue() + "\" />";
    }

    public void formatDate(DateElement e) {
        try {
            PresentationTemplate pt = e.getTemplate();
            SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yy");
            Calendar c = Calendar.getInstance();
            c.setTime(sdf.parse(e.getValue()));

            StringBuilder label = new StringBuilder("<label for=\"");
            label.append(pt.getAlias());
            label.append("day\">");
            label.append(Localization.getString(pt.getName()));
            label.append("</label>");

            StringBuilder daySelect = new StringBuilder();
            daySelect.append("<select class=\"day\" id=\"").append(pt.getAlias()).append("day\" name=\"").append(pt.getAlias()).append("day\" size=\"1\">");
            for (int i = 1; i < 32; i++) {
                daySelect.append("<option value=\"");
                daySelect.append(i);
                if (c.get(Calendar.DAY_OF_MONTH) == i) {
                    daySelect.append("\" selected=\"selected\">");
                } else {
                    daySelect.append("\">");
                }
                daySelect.append(i);
                daySelect.append("</option>");
            }
            daySelect.append("</select>");

            String months[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
            StringBuilder monthSelect = new StringBuilder();
            monthSelect.append("<select class=\"month\" id=\"").append(pt.getAlias()).append("month\" name=\"").append(pt.getAlias()).append("month\" size=\"1\">");
            for (int i = 1; i < 13; i++) {
                monthSelect.append("<option value=\"");
                monthSelect.append(i);
                if (c.get(Calendar.MONTH) + 1 == i) {
                    monthSelect.append("\" selected=\"selected\">");
                } else {
                    monthSelect.append("\">");
                }
                monthSelect.append(months[i - 1]);
                monthSelect.append("</option>");
            }
            monthSelect.append("</select>");

            StringBuilder yearSelect = new StringBuilder();
            yearSelect.append("<select class=\"year\" id=\"").append(pt.getAlias()).append("year\" name=\"").append(pt.getAlias()).append("year\" size=\"1\">");
            for (int i = 1970; i < 2012; i++) {
                yearSelect.append("<option value=\"");
                yearSelect.append(i);
                if (c.get(Calendar.YEAR) == i) {
                    yearSelect.append("\" selected=\"selected\">");
                } else {
                    yearSelect.append("\">");
                }
                yearSelect.append(i);
                yearSelect.append("</option>");
            }
            yearSelect.append("</select>");

            output = label.toString() + daySelect.toString() + monthSelect.toString() + yearSelect.toString();
        } catch (ParseException ex) {
        }
    }
}
